package com.crane.oss.web.controller.school;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.crane.common.core.dto.MultiResponse;
import com.crane.common.core.dto.Response;
import com.crane.common.core.dto.SingleResponse;
import com.crane.common.core.exception.AppException;
import com.crane.common.core.exception.BasicErrorCode;
import com.crane.common.core.utils.PhoneUtils;
import com.crane.common.core.utils.StringUtil;
import com.crane.common.framework.utils.BeanUtil;
import com.crane.oss.listener.UploadTeacherExcelListener;
import com.crane.oss.school.bean.request.QueryTeacherReq;
import com.crane.oss.school.bean.request.teacher.AddTeacherReq;
import com.crane.oss.school.bean.request.teacher.BatchOperateTeacherReq;
import com.crane.oss.school.bean.request.teacher.BatchImportTeacherEntity;
import com.crane.oss.school.bean.request.teacher.UpdateTeacherReq;
import com.crane.oss.school.bean.resp.ClassesInfoResp;
import com.crane.oss.school.bean.resp.OpenTeacherResp;
import com.crane.oss.school.bean.resp.TeacherExportResp;
import com.crane.oss.school.bean.resp.TeacherResp;
import com.crane.oss.school.service.ClassesInfoService;
import com.crane.oss.school.service.TeacherService;
import com.crane.oss.web.BaseBusinessController;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * @author zhenxing.pi
 * @email ccsu123456@qq.com
 * @date 2022年03月26日 14时24分54秒
 */

@Api(value = "TeacherController", tags = { "老师管理" })
@RestController
@RequestMapping("/school/teacher")
public class TeacherController extends BaseBusinessController {

	@Autowired
	TeacherService teacherService;

	@Autowired
	ClassesInfoService classesInfoService;

	@ApiOperation(value = "获取老师列表信息", notes = "获取老师列表信息：适用于老师列表、老师弹框列表")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "QueryTeacherReq")
	@RequiresPermissions("school:teacher:list")
	@PostMapping("/list")
	public MultiResponse<TeacherResp> list(@RequestBody QueryTeacherReq request) {
		request.setPartyId(getPartyId());
		IPage<TeacherResp> page = teacherService.queryList(request);
		return MultiResponse.of(page.getRecords(), (int) page.getTotal(), request);
	}

	@ApiOperation(value = "获得开课老师", notes = "获得开课老师信息：按校区分组返回")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "QueryTeacherReq")
	@RequiresPermissions("school:teacher:forOpen")
	@PostMapping("/forOpen")
	public MultiResponse<OpenTeacherResp> forOpen(@RequestBody QueryTeacherReq request) {
		request.setPartyId(getPartyId());
		List<OpenTeacherResp> teacherList = teacherService.queryOpenTeacherList(request);
		return MultiResponse.ofWithoutTotal(teacherList);
	}

	@ApiOperation(value = "根据班级查询教师", notes = "根据班级查询教师：查询班级任教老师")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "QueryTeacherReq")
	@RequiresPermissions("school:teacher:forClasses")
	@PostMapping("/forClasses")
	public MultiResponse<TeacherResp> forClasses(@RequestBody QueryTeacherReq request) {
		request.setPartyId(getPartyId());
		IPage<TeacherResp> page = teacherService.queryTeacherList(request);
		return MultiResponse.of(page.getRecords(), (int) page.getTotal(), request);
	}

	@ApiOperation(value = "新增老师", notes = "获取新增信息")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "AddTeacherReq")
	@RequiresPermissions("school:teacher:save")
	@PostMapping("/save")
	public Response save(@RequestBody @Valid AddTeacherReq request) {
		request.setPartyId(getPartyId());
		request.setCreateUserId(getUserId());
		teacherService.save(request);
		return Response.buildSuccess();
	}

	@ApiOperation(value = "未任教班级下拉列表", notes = "获取老师未任教班级下拉列表")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:classes")
	@GetMapping("/classes/{teacherId}")
	public MultiResponse classes(@PathVariable("teacherId") String teacherId) {
		List<ClassesInfoResp> classesList = classesInfoService.queryNotExistsClasses(Long.valueOf(teacherId), getPartyId());

		List<Map<String, Object>> list = new ArrayList<>();

		for (ClassesInfoResp classes : classesList) {
			Map<String, Object> map = new HashMap<>();
			map.put("key", classes.getClassId());
			map.put("name", classes.getClassName());
			list.add(map);
		}

		return MultiResponse.ofWithoutTotal(list);
	}

	@ApiOperation(value = "获取老师详细信息", notes = "获取老师详细信息")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:info")
	@GetMapping("/info/{teacherId}")
	public SingleResponse<TeacherResp> info(@PathVariable("teacherId") String teacherId) {
		TeacherResp teacherResp = teacherService.queryTeacher(Long.valueOf(teacherId));
		return SingleResponse.of(teacherResp);
	}

	@ApiOperation(value = "修改老师", notes = "修改老师信息")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "UpdateTeacherReq")
	@RequiresPermissions("school:teacher:update")
	@PostMapping("/update")
	public Response update(@RequestBody @Valid UpdateTeacherReq request) {
		request.setPartyId(getPartyId());
		request.setUpdateUserId(getUserId());
		teacherService.update(request);
		return Response.buildSuccess();
	}
	
	@ApiOperation(value = "批量删除老师", notes = "批量删除老师信息")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "BatchOperateTeacherReq")
	@RequiresPermissions("school:teacher:batchDelete")
	@PostMapping("/batchDelete")
	public Response batchDelete(@RequestBody @Valid BatchOperateTeacherReq request) {
		request.setUpdateUserId(getUserId());
		teacherService.batchDelete(request);
		return Response.buildSuccess();
	}

	@ApiOperation(value = "删除老师", notes = "删除老师")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:delete")
	@GetMapping("/delete/{teacherId}")
	public Response delete(@PathVariable("teacherId") String teacherId) {
		teacherService.delete(Long.valueOf(teacherId));
		return Response.buildSuccess();
	}
	
	@ApiOperation(value = "批量启用老师", notes = "批量启用老师信息")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "BatchOperateTeacherReq")
	@RequiresPermissions("school:teacher:batchEnable")
	@PostMapping("/batchEnable")
	public Response batchEnable(@RequestBody @Valid BatchOperateTeacherReq request) {
		request.setUpdateUserId(getUserId());
		teacherService.batchEnable(request);
		return Response.buildSuccess();
	}

	@ApiOperation(value = "启用老师", notes = "启用老师")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:enable")
	@GetMapping("/enable/{teacherId}")
	public Response enable(@PathVariable("teacherId") String teacherId) {
		teacherService.enable(Long.valueOf(teacherId));
		return Response.buildSuccess();
	}
	
	@ApiOperation(value = "批量禁用老师", notes = "批量禁用老师信息")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "BatchOperateTeacherReq")
	@RequiresPermissions("school:teacher:batchDisabled")
	@PostMapping("/batchDisabled")
	public Response batchDisabled(@RequestBody @Valid BatchOperateTeacherReq request) {
		request.setUpdateUserId(getUserId());
		teacherService.batchDisabled(request);
		return Response.buildSuccess();
	}

	@ApiOperation(value = "禁用老师", notes = "禁用老师")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:disabled")
	@GetMapping("/disabled/{teacherId}")
	public Response disabled(@PathVariable("teacherId") String teacherId) {
		teacherService.disabled(Long.valueOf(teacherId));
		return Response.buildSuccess();
	}
	
	@ApiOperation(value = "批量重置密码", notes = "批量重置密码")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "BatchOperateTeacherReq")
	@RequiresPermissions("school:teacher:batchReset")
	@PostMapping("/batchReset")
	public Response batchReset(@RequestBody @Valid BatchOperateTeacherReq request) {
		request.setUpdateUserId(getUserId());
		teacherService.batchReset(request);
		return Response.buildSuccess();
	}
	
	@ApiOperation(value = "重置密码", notes = "重置密码")
	@ApiImplicitParam(name = "teacherId", value = "老师id", paramType = "path", dataType = "String")
	@RequiresPermissions("school:teacher:reset")
	@GetMapping("/reset/{teacherId}")
	public Response reset(@PathVariable("teacherId") String teacherId) {
		teacherService.reset(Long.valueOf(teacherId));
		return Response.buildSuccess();
	}

	@ApiOperation(value = "下载模板", notes = "下载模板")
	@RequiresPermissions("school:teacher:download")
	@GetMapping("/download")
	public void download(HttpServletResponse response) {
		String dir = System.getProperty("user.dir") + "/";
		String path = dir + "teacher.xlsx";
		try {
			File file = new File(path);
			String filename = file.getName();

			InputStream fis = new BufferedInputStream(new FileInputStream(path));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();

			response.reset();

			response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
			response.addHeader("Content-Length", "" + file.length());
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/octet-stream");
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (Exception e) {
			e.printStackTrace();
			throw new AppException(BasicErrorCode.DEFINED_MSG, "下载模板失败");
		}
	}

	@ApiOperation(value = "批量导入", notes = "批量导入：xls xlsx")
	@RequestMapping(value = "/import", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8")
	@RequiresPermissions("school:teacher:import")
	@ResponseBody
	public MultiResponse batchImport(@RequestParam("file") @Valid MultipartFile upFile,
			@RequestParam("schoolId") @Valid Long schoolId) {
		String[] allowedType = { "application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" };
		boolean allowed = Arrays.asList(allowedType).contains(upFile.getContentType());
		if (!allowed) {
			throw new AppException(BasicErrorCode.FILE_FORMAT);
		}

		List<BatchImportTeacherEntity> returnList = new ArrayList<>();
		List<BatchImportTeacherEntity> saveList = new ArrayList<>();

		InputStream in = null;
		try {
			in = upFile.getInputStream();
			EasyExcel.read(in, BatchImportTeacherEntity.class, new UploadTeacherExcelListener()).sheet("Sheet1").doRead();

			for (BatchImportTeacherEntity teacher : UploadTeacherExcelListener.list) {
				String message = "";
				boolean returnFlag = false;
				BatchImportTeacherEntity entity = new BatchImportTeacherEntity();
				BeanUtil.copyProperties(teacher, entity);
				if (StringUtil.isEmpty(teacher.getName())) {
					if (StringUtil.isNotBlank(message)) {
						message = message+"|"+"姓名为空";
					} else {
						message = message+"姓名为空";
					}
					returnFlag = true;
				}
				if (StringUtil.isEmpty(teacher.getPhone())) {
					if (StringUtil.isNotBlank(message)) {
						message = message+"|"+"手机号码为空";
					} else {
						message = message+"手机号码为空";
					}
					returnFlag = true;
				} else {
					if (!PhoneUtils.isPhone(teacher.getPhone())) {
						if (StringUtil.isNotBlank(message)) {
							message = message+"|"+"手机号码格式不正确";
						} else {
							message = message+"手机号码格式不正确";
						}
						returnFlag = true;
					}
				}
				if (returnFlag) {
					entity.setMessage(message);
					returnList.add(entity);
				} else {
					saveList.add(entity);
				}
			}

			// 没有错误信息时批量保存
			if (0 == returnList.size()) {
				teacherService.batchSave(saveList, getPartyId(), getUserId(), schoolId);
			}

			UploadTeacherExcelListener.list.clear();
		} catch (Exception e) {
			e.printStackTrace();
			throw new AppException(BasicErrorCode.DEFINED_MSG, "批量导入老师失败");
		}

		return MultiResponse.ofWithoutTotal(returnList);
	}

	@ApiOperation(value = "批量导出", notes = "批量导出：导出为xls文档")
	@ApiImplicitParam(name = "request", value = "请求对象", required = true, dataType = "QueryTeacherReq")
	@RequiresPermissions("school:teacher:export")
	@PostMapping("/export")
	public void export(@RequestBody QueryTeacherReq request, HttpServletResponse response) {
		request.setPartyId(getPartyId());
		request.setPageSize(5000);
		IPage<TeacherExportResp> page = teacherService.queryExportList(request);
		if (page.getRecords().size() != 0) {
			ExcelWriter writer = ExcelUtil.getWriter();
			
			// 自定义标题别名
			writer.addHeaderAlias("name", "老师姓名");
			writer.addHeaderAlias("sexName", "性别");
			writer.addHeaderAlias("schoolName", "所属校区");
			writer.addHeaderAlias("account", "账号");
			writer.addHeaderAlias("phone", "手机号码");
			writer.addHeaderAlias("classesStr", "任教班级");
			writer.addHeaderAlias("typeName", "是否为体育教师");
			writer.addHeaderAlias("statusName", "状态");
			writer.addHeaderAlias("createTime", "创建时间");
			writer.write(page.getRecords(), true);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			String fileName = "老师";
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
			try {
				fileName = new String(fileName.getBytes(), "iso8859-1") + dateFormat.format(new Date());
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
			ServletOutputStream out = null;
			try {
				out = response.getOutputStream();
				writer.flush(out, true);
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				writer.close();
			}
			IoUtil.close(out);
		}
	}

}
